home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 28
/
Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso
/
Aminet
/
game
/
board
/
Exchess.lha
/
EXChess
/
book.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1998-08-17
|
15KB
|
545 lines
/* Book.Cpp functions to construct a book file from
a pgn-like text */
#include "chess.h"
#include "define.h"
#include "funct.h"
#include "const.h"
#include <stdio.h>
#include <string.h>
#include <iostream.h>
#include <fstream.h>
#include <math.h>
#include <time.h>
// define 64 bit integers
#if !BORLAND
#define __int64 long long
#define ZERO 0ULL
#else
#define ZERO 0ui64
#endif
#if DEC
#define IOS_OUT ios::out
#define IOS_IN ios::in
#else
#define IOS_OUT ios::out | ios::binary
#define IOS_IN ios::in | ios::binary
#endif
// Maximum line depth in ply
#define LINE_DEPTH 30
// Theshold of move score to use
#define THRESH 3
// Maximum number of book positions in a temp file
#define BOOK_POS 20000
// Maximum number of temp files
#define TEMP_FILES 200
struct book_rec {
unsigned __int64 pos_code;
int mcount;
move_rec bmoves[10];
int dummy; // to make record a multile byte size of 96
};
extern int T, shout_book; // Turn variable, loud book variable
typedef book_rec TT;
typedef book_rec TblIndex;
#define CompGT(a,b) (a > b)
void QuickSort(TT *Lb, TT *Ub);
void ISort(TT *Lb, TT *Ub);
float ran1(long *idum); // random number generator
int absl(int);
book_rec learn_book[100]; // book learning array
int learn_count = 0;
int learn_move[100];
int learn_filepos[100];
int chunk_count;
book_rec chunk_record[TEMP_FILES];
fstream chunk_file[TEMP_FILES];
extern char exec_path[100]; // from argv[0]
void build_book(position ipos)
{
book_rec *record, *record_place;
chunk_count = 1; int p, pp;
record = new book_rec[BOOK_POS];
// initialize record structure
for(p = 0; p < BOOK_POS; p++) {
record[p].pos_code = ZERO;
record[p].mcount = 0;
for(pp = 0; pp < 10; pp++) {
record[p].bmoves[pp].m.t = 0;
record[p].bmoves[pp].score = 0;
}
}
char file[20], instring[100], line[100], chunk[10];
position temp_pos;
move bmove;
unsigned __int64 pcode;
int i = -1, j = 0, k = 0, count = 0;
cout << " Enter name of book text file: ";
cin >> file;
cout << " Building book.... please wait.\n";
ifstream infile(file);
if(!infile) { cout << "File not found!\n"; return; }
infile.seekg(0,ios::end);
unsigned long file_size = infile.tellg();
infile.seekg(0,ios::beg);
while(!infile.eof()) {
infile >> instring;
switch(instring[0]) {
case '[':
i++; count=0; infile.getline(line,99); temp_pos = ipos; break;
case '1': break;
case '2': break;
case '3': break;
case '4': break;
case '5': break;
case '6': break;
case '7': break;
case '8': break;
case '9': break;
default :
count++; if(count > LINE_DEPTH) break;
bmove = parse_move(temp_pos, instring);
if(!bmove.t) { count = LINE_DEPTH; break; }
pcode = ZERO;
pcode = pcode|temp_pos.hcode.key;
pcode = (pcode<<32)|(temp_pos.hcode.address);
record_place = record;
for(j = 0; ; j++) {
if(record_place->pos_code == pcode ||
!record_place->pos_code) break;
record_place++;
}
if(!(j%1000) && j) {
cout << "Adding " << j << "th record to chunk "
<< chunk_count << ", " << (infile.tellg()*100)/file_size << "% done\n";
cout.flush();
}
record_place->pos_code = pcode;
for(k = 0; k < 10; k++)
{ if(record_place->bmoves[k].m.t == bmove.t
|| !record_place->bmoves[k].m.t) break; }
if(k < 10) {
record_place->bmoves[k].m.t = bmove.t;
record_place->bmoves[k].score++;
for(k = 0; k < 10; k++)
{ if(!record_place->bmoves[k].m.t) break; }
record_place->mcount = k;
}
exec_move(&temp_pos, bmove, 1);
break;
}
if (j>=BOOK_POS-1) {
if(chunk_count >= TEMP_FILES) break;
cout << "Sorting records for chunk " << chunk_count << "\n";
for(j = 0; j < BOOK_POS-1; j++)
{ record_place = record+j;
if(!record_place->pos_code) break; }
QuickSort(record, record_place-1);
sprintf(chunk, "temp_bk.%i", chunk_count);
chunk_file[chunk_count-1].open(chunk, IOS_IN | IOS_OUT);
for(i = 0; i < j; i++) {
record_place = record+i;
Sort(&record_place->bmoves[0],&record_place->bmoves[record_place->mcount-1]);
chunk_file[chunk_count-1].write((char *) record_place, sizeof(book_rec));
}
chunk_count++;
// initialize record structure
for(p = 0; p < BOOK_POS; p++) {
record[p].pos_code = ZERO;
record[p].mcount = 0;
for(pp = 0; pp < 10; pp++) {
record[p].bmoves[pp].m.t = 0;
record[p].bmoves[pp].score = 0;
}
}
j = 0;
}
}
for(j = 0; j < BOOK_POS-1; j++)
{ record_place = record+j;
if(!record_place->pos_code) break; }
cout << "Sorting records for last chunk\n ";
cout.flush();
QuickSort(record, record_place-1);
sprintf(chunk, "temp_bk.%i", chunk_count);
chunk_file[chunk_count-1].open(chunk, IOS_IN | IOS_OUT);
for(i = 0; i < j; i++) {
record_place = record+i;
Sort(&record_place->bmoves[0],&record_place->bmoves[record_place->mcount-1]);
chunk_file[chunk_count-1].write((char *) record_place, sizeof(book_rec));
}
ofstream out("open_bk.dat", IOS_OUT);
cout << "Writing book file...\n";
int min;
min = 0;
// first reading in a record from each chunk
for(i = 0; i < chunk_count; i++) {
if(chunk_file[i].eof()) { chunk_file[i].close(); break; }
chunk_file[i].seekg(0,ios::beg);
chunk_file[i].read((char *) &chunk_record[i], sizeof(book_rec));
}
while(1) {
// Now probe for minimum entry
min = 0;
for(i = 0; i < chunk_count; i++) {
if(min == i && !chunk_record[i].pos_code) { min++; continue; }
if(chunk_record[min].pos_code > chunk_record[i].pos_code &&
chunk_record[i].pos_code) min = i;
}
if(min == chunk_count) break;
// merge all minimum records together - reading in more when necessary
for(i = 0; i < chunk_count; i++) {
if(i == min) continue;
if(chunk_record[min].pos_code == chunk_record[i].pos_code) {
// merging records
for(j = 0; j < chunk_record[min].mcount; j++) {
for(k = 0; k < chunk_record[i].mcount; k++) {
if(chunk_record[min].bmoves[j].m.t == chunk_record[i].bmoves[k].m.t) {
chunk_record[min].bmoves[j].score += chunk_record[i].bmoves[k].score;
chunk_record[i].bmoves[k].score = -1; // flag it as merged
break;
}
}
}
for(k = 0 ; k < chunk_record[i].mcount; k++) {
if(chunk_record[i].bmoves[k].score > 0 && j < 10) {
chunk_record[min].bmoves[j].m.t = chunk_record[i].bmoves[k].m.t;
chunk_record[min].bmoves[j].score = chunk_record[i].bmoves[k].score;
j++;
}
}
chunk_record[min].mcount = j;
Sort(&chunk_record[min].bmoves[0],&chunk_record[min].bmoves[j-1]);
if(!chunk_file[i].eof())
chunk_file[i].read((char *) &chunk_record[i], sizeof(book_rec));
else chunk_record[i].pos_code = ZERO;
}
}
if (chunk_record[min].bmoves[0].score >= THRESH)
out.write((char *) &chunk_record[min], sizeof(book_rec));
if(!chunk_file[min].eof())
chunk_file[min].read((char *) &chunk_record[min], sizeof(book_rec));
else chunk_record[min].pos_code = ZERO;
}
// remove temporary files
for(j = 1; j <= chunk_count; j++) {
chunk_file[j-1].close();
sprintf(chunk, "temp_bk.%i", j);
if(remove(chunk) == -1) cout << "Error deleting " << chunk << "\n";
}
out.close();
delete [] record;
}
move opening_book(h_code hash_code, position *p)
{
unsigned __int64 pcode = ZERO;
book_rec